 ;; missd8.lsp
;; Copyright (c) 1998 by Pedro Valero (valerop@uv.es)
;; Code for monitoring elementwise convergence
;; 
;; 
;;########################################################################

(defmeth missing-data-model-object-proto :spreadplot-convergence ()
 	(let* (
         (list-matrix-prev-convergence          
          (mapcar 
           '(lambda (x) 
              (combine (select x 0 (iseq 1  (1- (array-dimension x 0))))
                       (matrix-to-list 
                        (select x
                                (iseq 1 (1- (array-dimension x 0)))
                                (iseq 1 (1- (array-dimension x 0)))))
                       (rest (diagonal x))))
           (send self :elementwise-convergence)))
         (list-matrix-convergence 
          (transpose 
           (make-array 
            (list 
             (length 
              list-matrix-prev-convergence)
             (length (first list-matrix-prev-convergence))) 
            :initial-contents 
            (combine list-matrix-prev-convergence))))
         (rate-convergence (send self :compute-elementwise-convergence))
         (list-matrix-prev 
          (mapcar 
           '(lambda (x) 
              (combine (select x 0 (iseq 1  (1- (array-dimension x 0))))
                       (matrix-to-list 
                        (select x
                                (iseq 1 (1- (array-dimension x 0)))
                                (iseq 1 (1- (array-dimension x 0)))))
                       (rest (diagonal x))))
           rate-convergence))

         (list-matrix (transpose (make-array (list 
                                 (length 
                                  list-matrix-prev)
                                 (length (first list-matrix-prev))) 
                                             :initial-contents 
                                             (combine list-matrix-prev))))
         (bxplot 
          (plot-points (iseq (array-dimension list-matrix 1))
                       (first (row-list list-matrix)) 
                       :show nil :title "Proportion of missing info"))
         (iter (array-dimension list-matrix 1))
         (n (array-dimension list-matrix 0))
         (bxplot2 
          (plot-points (iseq (array-dimension list-matrix-convergence 1))
                       (first (row-list list-matrix-convergence )) 
                        :show nil :title "Parametter Change"))
         (list-vars 
          (name-list  
           (combine (mapcar '(lambda (x)
                               (concatenate 'string "mean_" x ))
                            (send self :variables))
                    (mapcar '(lambda (x)
                               (concatenate 'string "Covar_" x ))
                            (first (send self :listvariables)))
                    (mapcar '(lambda (x)
                               (concatenate 'string "Variance_" x ))
                            (send self :variables))) :show nil :title "Parameters"))

         (iter-plot (plot-points (iseq (length (send self :iter-logs))) 
                                 (send self :iter-difs) :show nil :title "Difference"))
         (logs-plot (plot-points (iseq (length (send self :iter-logs))) 
                                 (send self :iter-logs) :show nil :title "Loglikelihood"))
         
         (sp nil)
         )
     (send list-vars :use-color t)
    (send list-vars :point-color (iseq (send list-vars :num-points)) 'blue)
    (send iter-plot :use-color t)
    (send iter-plot :point-color (iseq (send iter-plot :num-points)) 'blue)
    (send logs-plot :use-color t)
    (send logs-plot :point-color (iseq (send logs-plot :num-points)) 'blue)
    (send bxplot :use-color t)
    (send bxplot :point-color (iseq (send bxplot :num-points)) 'blue)
    (send bxplot2 :use-color t)
    (send bxplot2 :point-color (iseq (send bxplot2 :num-points)) 'blue)
    (send bxplot :scaled-range 1 -1 1)
    (send bxplot :add-lines (iseq (array-dimension list-matrix 1))
                       (first (row-list list-matrix)) :color 'red)
    (send bxplot :abline 0 0 )
    (send bxplot2 :add-lines (iseq (array-dimension list-matrix-convergence 1))
                       (first (row-list list-matrix-convergence )):color 'red)
    (send bxplot2 :adjust-to-data)
    (send iter-plot :add-lines (iseq (length (send self :iter-logs))) (send self :iter-difs) :color 'red)
    (send logs-plot :add-lines (iseq (length (send self :iter-logs))) (send self :iter-logs) :color 'red)
    (send bxplot :point-label (iseq  (* iter n)) 
          (mapcar 'princ-to-string (combine list-matrix)))

   (setf sp
         (spread-plot 
          (matrix (list 2 3) 
                  (list list-vars bxplot bxplot2  nil iter-plot logs-plot))
          :local-links t
          :show t
          :rel-widths (list 1 1 1)
          :span-down (matrix (list 2 3) (list 2 1 1 0 1 1))))


   (defmeth list-vars
      :do-click (a b c d)   
     (call-next-method a b c d)               
     (send bxplot :clear)
     (send bxplot :abline 0 0)
     (mapcar #'(lambda (sel) 
                 
                 (send bxplot :add-lines 
                       (iseq (array-dimension list-matrix 1))
                       (select (row-list list-matrix) sel) :color 'red)
                      (send bxplot :add-points 
                            (iseq (array-dimension list-matrix 1)) 
                            (select (row-list list-matrix) sel))
                 )
                 (send self :selection))

     (send bxplot :use-color t)
     (send bxplot 
           :scaled-range 1 -1 1 :draw t)
                 

     (send bxplot :point-color
       (iseq (send    bxplot :num-points))
           'blue)
     (send bxplot2 :redraw)


     (send bxplot2 :start-buffering)
     (send bxplot2 :clear)

     (mapcar #'(lambda (sel) 
                 
                 (send bxplot2 :add-points 
                       (iseq (array-dimension list-matrix-convergence 1)) 
                       (mapcar #'(lambda (v) (if (< (abs v) 0.000001) v 0))
                              (coerce  (select (row-list list-matrix-convergence) sel) 'list)))
                
                 (send bxplot2 :add-lines 
                       (iseq (array-dimension list-matrix-convergence 1)) 
                       (mapcar #'(lambda (v) (if (< (abs v) 0.000001) v 0))
                              (coerce  (select (row-list list-matrix-convergence) sel) 'list)) :color 'red)
                 )
             (send self :selection))

     (send bxplot2 :use-color t)
     (send bxplot2 :point-color
            (iseq  (send bxplot :num-points))
            'blue)
     (send bxplot2 :adjust-to-data)
     (send bxplot2 :buffer-to-screen)
     )
      

  (defmeth bxplot
  :do-click (a b c d)   
  (call-next-method a b c d)               
  (send 
   bxplot2 :selection  
   (1+ (send bxplot :selection)))
  )
 (defmeth bxplot2
  :do-click (a b c d)   
  (call-next-method a b c d)               
  (send 
   bxplot :selection  
   (1- (send bxplot2 :selection)))
  )

(defmeth logs-plot
  :do-click (a b c d)   
  (call-next-method a b c d)               
  (send 
   iter-plot :selection  
   (send logs-plot :selection))
  )

(defmeth iter-plot
      :do-click (a b c d)   
  (call-next-method a b c d)               
  (send 
   logs-plot :selection  
   (send iter-plot :selection))
  )

    (send bxplot
                :plot-buttons 
                :margin (list 0 17 0 0) 
                :new-x nil 
                :new-y nil 
                :mouse-mode t)
    (defmeth bxplot :plot-help ()
      (plot-help-window (strcat "Help for " (send self :title)))
      (paste-plot-help (format nil ""))
      (show-plot-help))
    (send bxplot2
                :plot-buttons 
                :margin (list 0 17 0 0) 
                :new-x nil 
                :new-y nil 
                :mouse-mode t)
    (defmeth bxplot2 :plot-help ()
      (plot-help-window (strcat "Help for " (send self :title)))
      (paste-plot-help (format nil ""))
      (show-plot-help))

    (send logs-plot
                :plot-buttons 
                :margin (list 0 17 0 0) 
                :new-x nil 
                :new-y nil 
                :mouse-mode t)
    (defmeth logs-plot :plot-help ()
      (plot-help-window (strcat "Help for " (send self :title)))
      (paste-plot-help (format nil ""))
      (show-plot-help))

    (send iter-plot
                :plot-buttons 
                :margin (list 0 17 0 0) 
                :new-x nil 
                :new-y nil 
                :mouse-mode t)
    (defmeth iter-plot :plot-help ()
      (plot-help-window (strcat "Help for " (send self :title)))
      (paste-plot-help (format nil ""))
      (show-plot-help))

    (send list-vars
                :plot-buttons 
                :margin (list 0 17 0 0) 
                :new-x nil 
                :new-y nil 
                :mouse-mode t)
    (defmeth list-vars :plot-help ()
      (plot-help-window (strcat "Help for " (send self :title)))
      (paste-plot-help (format nil ""))
      (show-plot-help))
    ))
    

(defmeth missing-data-model-object-proto :compute-elementwise-convergence ()
  
  (let* (
         (matrix-convergences (send self :elementwise-convergence))         
         (n-rows (array-dimension (first matrix-convergences) 0))
         (n-columns (array-dimension (first matrix-convergences) 1))
         (res (make-array (array-dimensions (first matrix-convergences))))
         (results nil)
         
         ;(mindifference (/ (send self :difference) 100))
         )
    
    (dotimes (h (1- (length matrix-convergences)))
     (dotimes (i n-rows)
              (dotimes (j n-columns)
                      (when (> h 0)
                            (setf (select res i j)
                                 ; (if 
                                  ; (< (abs (-  (select (select matrix-convergences h) i j)
                                   ;            (select (select matrix-convergences (1- h)) i j)))
                                    ;  mindifference) ;to prevent numerical unstability
                                   
                                   ;0
                                    (if (> (abs (-  (select (select matrix-convergences h) i j)
                                       (select (select matrix-convergences (1- h)) i j))) 0)
                                   (/
                                    (- (select (select matrix-convergences (1+ h)) i j)
                                      (select (select matrix-convergences h) i j))
                                    (-  (select (select matrix-convergences h) i j)
                                       (select (select matrix-convergences (1- h)) i j)))
                                        0)
                                  ; )
                                  ))     
                       ))
             (setf results (append results (list (copy-array res))))
             )
   (cdr results)))




;funcion para explorar elementwise-convergence 

;(boxplot-elementwise-convergence (send current-object :elementwise-convergence))       


 

                     


